﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WordNet.Core.DataContract;
using DataFileProvider;

namespace WordNet.Core
{
    public class FileProvider<T> : IDataProvider<T>
    {
        private readonly HashSet<IContentType<T>> _types;
        private Uri _uri;
        private Dictionary<IContentType<T>, IDataSource> _fileMap;
       
        public FileProvider(Uri uri) : this(uri, ContentType<T>.Values) { }
        public FileProvider(Uri uri, IEnumerable<IContentType<T>> types)
        {
            if (uri == null)
                throw new ArgumentNullException();
            if (types.Count() == 0)
                throw new ArgumentException();
            _uri = uri;
            _types = new HashSet<IContentType<T>>(types);
        }
       
        public void Close()
        {
            this._fileMap = null;
        }

        public IDataSource GetSourceForContentType(IContentType<T> type)
        {
            return _fileMap[type];
        }

        public ISet<IContentType<T>> GetTypes()
        {
            return _types as ISet<IContentType<T>>;
        }

        public bool IsOpen
        {
            get { return _fileMap != null; }
        }

        public void Open()
        {
            DirectoryInfo directory = new DirectoryInfo(_uri.LocalPath);
            if (!directory.Exists)
                throw new IOException();

            this._fileMap = CreateSourceMap(directory);
        }

        public Uri Source
        {
            get
            {
                return _uri;
            }
            set
            {
                if (IsOpen)
                    throw new NotSupportedException();
                _uri = value;
            }
        }

        protected Dictionary<IContentType<T>, IDataSource> CreateSourceMap(DirectoryInfo dir)
        {
            Dictionary<IContentType<T>, IDataSource> result = new Dictionary<IContentType<T>, IDataSource>();
            FileInfo file = null;
            foreach (IContentType<T> type in _types)
            {
                try
                {
                    file = new FileInfo(string.Format("{0}/{1}", dir.FullName, type.FileName));
                }
                catch
                {
                    file = null;
                    continue;
                }
                result.Add(type, new WordNetFile(file));
            }

            return result;
        }
    }
}
